package com.micro.ai.commons.util;

import lombok.extern.slf4j.Slf4j;

import java.security.SecureRandom;
import java.util.UUID;

/**
 * ID生成器工具类
 * 
 * @author micro-ai
 * @since 0.0.1
 */
@Slf4j
public final class IdGenerator {

    private IdGenerator() {
        throw new UnsupportedOperationException("工具类不允许实例化");
    }

    /**
     * 生成UUID
     */
    public static String generateUuid() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 生成带连字符的UUID
     */
    public static String generateUuidWithHyphens() {
        return UUID.randomUUID().toString();
    }

    /**
     * 生成短UUID（8位）
     */
    public static String generateShortUuid() {
        return generateUuid().substring(0, 8);
    }

    /**
     * 生成随机字符串
     */
    public static String generateRandomString(int length) {
        if (length <= 0) {
            throw new IllegalArgumentException("长度必须大于0");
        }
        
        String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        SecureRandom random = new SecureRandom();
        StringBuilder sb = new StringBuilder(length);
        
        for (int i = 0; i < length; i++) {
            sb.append(chars.charAt(random.nextInt(chars.length())));
        }
        
        return sb.toString();
    }

    /**
     * 生成数字随机字符串
     */
    public static String generateRandomNumberString(int length) {
        if (length <= 0) {
            throw new IllegalArgumentException("长度必须大于0");
        }
        
        SecureRandom random = new SecureRandom();
        StringBuilder sb = new StringBuilder(length);
        
        for (int i = 0; i < length; i++) {
            sb.append(random.nextInt(10));
        }
        
        return sb.toString();
    }

    /**
     * 生成雪花算法ID（Long类型）
     */
    public static Long generateSnowflakeId() {
        return SnowflakeIdGenerator.getInstance().nextId();
    }

    /**
     * 生成雪花算法ID（String类型）
     */
    public static String generateSnowflakeIdString() {
        return String.valueOf(generateSnowflakeId());
    }

    /**
     * 雪花算法ID生成器
     */
    private static class SnowflakeIdGenerator {
        
        private static final SnowflakeIdGenerator INSTANCE = new SnowflakeIdGenerator();
        
        // 起始时间戳（2023-01-01 00:00:00）
        private static final long START_TIMESTAMP = 1672531200000L;
        
        // 机器ID位数
        private static final long MACHINE_BIT = 5;
        
        // 数据中心ID位数（预留用于扩展）
        // private static final long DATACENTER_BIT = 5;
        
        // 序列号位数
        private static final long SEQUENCE_BIT = 12;
        
        // 机器ID最大值（预留用于验证）
        // private static final long MAX_MACHINE_NUM = ~(-1L << MACHINE_BIT);
        
        // 数据中心ID最大值（预留用于验证）
        // private static final long MAX_DATACENTER_NUM = ~(-1L << DATACENTER_BIT);
        
        // 序列号最大值
        private static final long MAX_SEQUENCE = ~(-1L << SEQUENCE_BIT);
        
        // 机器ID左移位数
        private static final long MACHINE_LEFT = SEQUENCE_BIT;
        
        // 数据中心ID左移位数（预留用于扩展）
        // private static final long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
        
        // 时间戳左移位数
        private static final long TIMESTAMP_LEFT = SEQUENCE_BIT + MACHINE_BIT;
        
        private final long machineId;
        // private final long datacenterId; // 预留用于扩展
        private long sequence = 0L;
        private long lastTimestamp = -1L;
        
        private SnowflakeIdGenerator() {
            this.machineId = getMachineId();
            // this.datacenterId = getDatacenterId(); // 预留用于扩展
        }
        
        public static SnowflakeIdGenerator getInstance() {
            return INSTANCE;
        }
        
        public synchronized long nextId() {
            long currentTimestamp = getCurrentTimestamp();
            
            if (currentTimestamp < lastTimestamp) {
                throw new RuntimeException("时钟回拨，拒绝生成ID");
            }
            
            if (currentTimestamp == lastTimestamp) {
                sequence = (sequence + 1) & MAX_SEQUENCE;
                if (sequence == 0L) {
                    currentTimestamp = getNextTimestamp();
                }
            } else {
                sequence = 0L;
            }
            
            lastTimestamp = currentTimestamp;
            
            return (currentTimestamp - START_TIMESTAMP) << TIMESTAMP_LEFT
                    | machineId << MACHINE_LEFT
                    | sequence;
        }
        
        private long getCurrentTimestamp() {
            return System.currentTimeMillis();
        }
        
        private long getNextTimestamp() {
            long timestamp = getCurrentTimestamp();
            while (timestamp <= lastTimestamp) {
                timestamp = getCurrentTimestamp();
            }
            return timestamp;
        }
        
        private long getMachineId() {
            // 这里可以根据实际部署情况获取机器ID
            // 可以从环境变量、配置文件或网络接口获取
            return 1L;
        }
        
        // private long getDatacenterId() {
        //     // 这里可以根据实际部署情况获取数据中心ID
        //     // 可以从环境变量、配置文件或网络接口获取
        //     return 1L;
        // }
    }
}
